package edu.caltech.android.c2dm;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.util.Log;

/**
 * Register/unregister with the App Engine server.
 */
public class DeviceRegistrar {
	public static final String STATUS_EXTRA = "Status";
	public static final int REGISTERED_STATUS = 1;
	public static final int AUTH_ERROR_STATUS = 2;
	public static final int UNREGISTERED_STATUS = 3;
	public static final int ERROR_STATUS = 4;

	private static final String TAG = "DeviceRegistrar";

	// An email account associated with the application's developer. The sender
	// ID is used in the registration process to identify a Android application
	// that is permitted to send messages to the device. This ID is typically
	// role-based rather than being a personal account—- for example,
	// my-app@gmail.com.
	public static final String SENDER_ID = "csn.bot@gmail.com"; 

	private static final String REGISTER_PATH = "/c2dm/register";
	private static final String UNREGISTER_PATH = "/c2dm/unregister";

	public static void registerWithServer(final Context context,
			final String deviceRegistrationID) {
		new Thread(new Runnable() {
			public void run() {

				Intent updateUIIntent = new Intent(
						SetupActivity.UPDATE_UI_ACTION);
				try {
					HttpResponse res = makeRequest(context,
							deviceRegistrationID, REGISTER_PATH);
					if (res.getStatusLine().getStatusCode() == 200) {
						Log.w(TAG, "got registrationID");
						SharedPreferences settings = Prefs.get(context);
						SharedPreferences.Editor editor = settings.edit();
						editor.putString("deviceRegistrationID",
								deviceRegistrationID);
						editor.commit();
						updateUIIntent
								.putExtra(STATUS_EXTRA, REGISTERED_STATUS);
					} else if (res.getStatusLine().getStatusCode() == 400) {
						Log.w(TAG, "auth error?");
						updateUIIntent
								.putExtra(STATUS_EXTRA, AUTH_ERROR_STATUS);
					} else {
						Log.w(TAG, "Registration error "
								+ String.valueOf(res.getStatusLine()
										.getStatusCode())
								+ " " + res.getStatusLine().getReasonPhrase());

						updateUIIntent.putExtra(STATUS_EXTRA, ERROR_STATUS);
					}
					context.sendBroadcast(updateUIIntent);
				} catch (AppEngineClient.PendingAuthException pae) {
					// Ignore - we'll reregister later
				} catch (Exception e) {
					Log.w(TAG, "Registration exception " + e.getMessage());
					updateUIIntent.putExtra(STATUS_EXTRA, ERROR_STATUS);
					context.sendBroadcast(updateUIIntent);
				}
			}
		}).start();
	}

	public static void unregisterWithServer(final Context context,
			final String deviceRegistrationID) {
		new Thread(new Runnable() {
			public void run() {
				// Intent updateUIIntent = new
				// Intent("com.google.ctp.UPDATE_UI");
				try {
					HttpResponse res = makeRequest(context,
							deviceRegistrationID, UNREGISTER_PATH);
					if (res.getStatusLine().getStatusCode() == 200) {
						SharedPreferences settings = Prefs.get(context);
						SharedPreferences.Editor editor = settings.edit();
						editor.remove("deviceRegistrationID");
						editor.commit();
						// updateUIIntent.putExtra(STATUS_EXTRA,
						// UNREGISTERED_STATUS);
					} else {
						Log.w(TAG, "Unregistration error "
								+ String.valueOf(res.getStatusLine()
										.getStatusCode()));
						// updateUIIntent.putExtra(STATUS_EXTRA, ERROR_STATUS);
					}
				} catch (Exception e) {
					// updateUIIntent.putExtra(STATUS_EXTRA, ERROR_STATUS);
					Log.w(TAG, "Unegistration error " + e.getMessage());
				}

				// Update dialog activity
				// context.sendBroadcast(updateUIIntent);
			}
		}).start();
	}

	/**
	 * Put together the client-to-application-server registration request.
	 * 
	 * @param context
	 * @param deviceRegistrationID
	 * @param urlPath
	 * @return
	 * @throws Exception
	 */
	private static HttpResponse makeRequest(Context context,
			String deviceRegistrationID, String urlPath) throws Exception {
		SharedPreferences settings = Prefs.get(context);
		String accountName = settings.getString("accountName", null);

		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("devregid", deviceRegistrationID));

		String deviceId = Secure.getString(context.getContentResolver(),
				Secure.ANDROID_ID);
		if (deviceId != null) {
			params.add(new BasicNameValuePair("deviceId", deviceId));
		}

		// TODO: Allow device name to be configured
		params.add(new BasicNameValuePair("deviceName", "Phone"));

		AppEngineClient client = new AppEngineClient(context, accountName);
		return client.makeRequest(urlPath, params);
	}

}
